package org.zn.note.mybatis.setting;

import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
import org.apache.ibatis.reflection.factory.ObjectFactory;

import java.util.Collection;
import java.util.List;
import java.util.Properties;

import static org.zn.note.mybatis.util.MyBatisUtils.DEBUG;

/**
 * MyBatis对象工厂
 * 每次 MyBatis 创建结果对象的新实例时，它都会使用一个对象工厂（ObjectFactory）实例来完成实例化工作。
 * 默认的对象工厂需要做的仅仅是实例化目标类，要么通过默认无参构造方法，要么通过存在的参数映射来调用带有参数的构造方法。
 * 如果想覆盖对象工厂的默认行为，可以通过创建自己的对象工厂来实现。
 * <p>
 * 1、实现 {@link ObjectFactory} (MyBatis默认的是 {@link DefaultObjectFactory})
 * 2、XML配置 <objectFactory>
 */
public class MyObjectFactory extends DefaultObjectFactory {

    @Override
    public <T> T create(Class<T> type) {
        if (DEBUG)
            System.out.printf("This is ExampleObjectFactory.create1: %s\n", type.getSimpleName());
        return super.create(type);
    }

    @Override
    public <T> T create(Class<T> type, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) {
        if (DEBUG)
            System.out.printf("This is ExampleObjectFactory.create2: %s\n", type.getSimpleName());
        return super.create(type, constructorArgTypes, constructorArgs);
    }

    @Override
    public void setProperties(Properties properties) {
        if (DEBUG)
            System.out.printf("This is ExampleObjectFactory.setProperties: %s\n", properties);
        super.setProperties(properties);
    }

    public <T> boolean isCollection(Class<T> type) {
        if (DEBUG)
            System.out.printf("This is ExampleObjectFactory.isCollection: %s\n", type.getSimpleName());
        return Collection.class.isAssignableFrom(type);
    }
}
